perm filename INPROC.MAC[IP,SYS] blob sn#680212 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-INET>INPROC.MAC.40303 12-Apr-82 20:48:25, Edit by CLYNN
;<CLYNN.REL3>INPROC.MAC.40302 27-Mar-82 21:19:17, Edit by CLYNN
; Moved calls to WTBINI and FREINI before DISL(NETSUP) for standalone
;<403-INET>INPROC.MAC.40301 29-Jan-82 15:13:38, Edit by CLYNN
; Updated for IP release 3
;<402-INET>INPROC.MAC.25, 22-Sep-81 11:58:20, Edit by TAPPAN
; reorder things in INTINI to avoid race condition with jobs
; logging out before special Q's are initialized
;SNARK:<402-INET>INPROC.MAC.22 10-Feb-81 09:59:15, Edit by CLYNN
;PINGTM should be compared to the TODCLK, not TCPTIM
;	INTBP1+17	MOVE T1,TCPTIM		MOVE T1,TODCLK
;			CAMGE T1,PINGTM		CAMGE T1,PINGTM
;[BBND]SNARK:<402-INET>INPROC.MAC.21, 29-Dec-80 14:39:16, Ed: TAPPAN
;	INTRBF+5	XMOVEI T1,-IMP96L(T2)	XMOVEI T1,-LCLPKT(T2)
;	RETPKT+4	XMOVEI T2,IMP96L(PKT)	XMOVEI T2,LCLPKT(PKT)

	SEARCH	INPAR,TCPPAR,IMPPAR,PROLOG
	TTITLE	INPROC
	SUBTTL	Internet Process, William W. Plummer, 28Feb79
	SWAPCD

COMMENT	!
These routines control the running of the various Internet processes
such as the Internet User Queue mechansism, TCP, etc.
This process keeps a supply of input buffers available for the
various interfaces and handles returning of spent buffers.

* INTBEG ..  3 ...... Start up the Internet fork
  INTBP0 ..  3 ...... Start of the Internet fork code
  INTBP1 ..  4 ...... Top of main loop
  INTUXI ..  6 ...... Unexpected Interrupt handler
* INTBPT ..  6 ...... Scheduler activation test to Internet fork

  INTNRB ..  7 ...... Release empty output bfrs left by interrupt level
  INTRBF ..  7 ...... Release one empty Internet bfr (packet, segment)
  INTGIB ..  8 ...... Get a supply of packet buffers for input
* RETPKT ..  9 ...... Release packet storage

* INETUT .. 10 ...... Get universal time since midnight

  INTINI .. 11 ...... Grand initialization
	!

; Default local parameter:

NINTIB==4*%NETS	; Number of input buffers to keep queued for PI level
		; Dynamic variable is INTNIB

; INTBEG	Start the Internet process at system startup time.

;	CALL INTBEG
;Ret+1:	Always.

INTBEG::MOVSI T1,(CR%CAP)
	CFORK			; Get a fork of JOB0
	 INBUG (HLT,<INTBEG: Can't create Internet fork>,INTMA0)
	XMOVEI T2,INTBP0
	MSFRK			; Start fork in monitor mode
	RET


; Internet fork top level

INTBP0::MOVSI T1,(PC%USR)	; User mode bit
	MOVEM T1,FPC		; Fake a return PC
	MCENTR			; Establish monitor context
	SE1ENT
IFKL <	MOVX T1,.FHSLF		; Give internet fork some priority
	MOVX T2,001		; Only allow queue 0
	SPRIW%
	  ERJMP .+1
	CALL SETSPQ		; INT runs on high priority queue
> ; End of IFKL
IFKA <
  IFE PIESLC,<
	MOVEI 1,202
	MOVEM 1,JOBBIT
  > ; End of IFE PIESLC
  IFN PIESLC,<
	CALL SETSPQ
  > ; End of IFN PIESLC
> ; End of IFKA
	MOVE T1,FORKX		; ID of this fork
	MOVEM T1,INTFRK		; Save for debugging
	MOVE T1,[ITFPC,,INTUXI]
	MOVEM T1,MONBK		; Setup unexpected interrupt dispatch
	MOVE T1,CHNSON
	MOVEM T1,MONCHN		; Setup for panic channels
	CALL INTINI		; Initialize everything

PIX==5
PTB==6
PTL==7

INTBP1:	PUSH P,[MSEC1,,INTBP1]	; Return for following routines.
	SETZM INTFLG		; Clear forced run flag.

	MOVE T1,TODCLK		; Check if time to discard
	CAML T1,INTRAT		; timedout IP fragments
	  CALL RCVFLS		; Yes

	SKIPE INTIBO		; Packets waiting for dispatch?
	  CALL INTDSP		; Yes.  Hand them out to TCP, etc.

	SKIPE INTNFB		; Any empty output buffers around?
	  CALLRET INTNRB	; Yes.  Go release them.

	MOVE T1,INTNFI		; Number of free input buffers
	CAMGE T1,INTNIB		; Below desired level?
	  CALL INTGIB		; Yes.  Go queue some more for PI level.

;	SKIPE INTSCR		; Using the Raw Packet Interface
;	 CALL RPICHK		; Maybe give it an input buffer

	MOVEI PTB,INTPIX+1
	MOVE PIX,-1(PTB)
	HRRZ PTL,PIX

INTBP3:	SKIPLE T2,.INTPP(PTB)	; Processing routine
	 SKIPN .INTPO(PTB)	; Check if its ON
	  JRST INTBP4		; Skip it if no routine or not on

	MOVE T1,.INTPT(PTB)	; Next run time
	CAMLE T1,TODCLK		; Call if time to run
	 SKIPE .INTPF(PTB)	; or run flag set
	  CALL (T2)		; Call protocol processor

INTBP4:	ADD PTB,PTL
	AOBJN PIX,INTBP3

	HRLOI T1,377777		; Next run time unless needed sooner

	MOVEI PTB,INTPIX+1
	MOVE PIX,-1(PTB)
	HRRZ PTL,PIX

INTBP6:	SKIPLE T2,.INTPC(PTB)	; Time check routine
	  CALL (T2)		; Call protocol time checker
	ADD PTB,PTL
	AOBJN PIX,INTBP6

	MOVEM T1,INTTIM		; Set wakup
	JSP T4,INTBPT		; Run the test at process level
	 CAIA			; To save overhead of scheduler
	  RET			; Back to INTBP1
	MOVEI T1,INTBPT		; Select the activation test
;	MDISMS			; Wait til it is satisifed
	HDISMS 500		; Keep us around half a second
	RET

	PURGE PIX,PTB,PTL
; Unexpected interrupt

INTUXI:	INBUG(CHK,<Internet fork: unexpected interrupt>,INTMA1)
IFKA <	MOVSI T1,(PC%USR)	; Reset UPDL
	MOVEM T1,FPC
>
IFNKA <	SE1ENT>			; Enter section 1
	MCENTR
	JRST INTBP1




; INTBPT	Scheduler activation test for Internet fork

;	JSP T4,INTBPT
;Ret+1:	Internet fork not ready to run
;Ret+2:	Internet fork runnable

	RESCD
INTBPT::SKIPE INTFLG		; Forced run?
	 JRST 1(T4)		; Yes.
	MOVE T1,TODCLK		; Current millisecond number
	CAML T1,INTTIM		; After desired wakeup time?
	 JRST 1(T4)		; Yes.
	JRST 0(T4)
	SWAPCD

; Release packet buffers left by PI level (mostly empty output packets)

;INTNFB/List of freed buffers
;
;	CALL INTNRB
;Ret+1:	Always

INTNRB:	SETZ T4,
	EXCH T4,INTNFB		; Get and clear free list
INTNR1:	SKIPN T4		; Quit at end of list
	 RET
	SETSEC T4,INTSEC	; Make extended address
	XMOVEI T2,0(T4)		; Pointer to IMPDV part of packet
	LOAD T4,NBQUE,(T4)	; Pointer to CDR of list
	CALL INTRBF		; Release on buffer to INT free area
	JRST INTNR1




; INTRBF		Release an IMPDV-style packet to INT free area

;T2/	(Extended) Pointer to IMPDV portion of packet
;T4/	MUST BE PRESERVED
;
;	CALL INTRBF
;Ret+1:	Always

INTRBF::PUSH P,T4		; Save this as required.
	PUSH P,T2
	MOVE T1,T2
	CALL INTULK		; Unlock the packet
	POP P,T2		; Get back IMP style pointer
	XMOVEI T1,-LCLPKT(T2)	; Compute standard Internet pointer
	SETZRO PINTL,(T1)	; No longer in use by interrupt level
	JN PPROG,(T1),INTRBX	; Do RETBLK if REMSEQ won't do it.
	CALL RETBLK		; Release it (assume not full size)
INTRBX:	POP P,T4
	RET

; INTGIB			Get input buffers

; Called to pump up the list of free input buffers used by the
; input PI routines.  If this is not done often enough, INT messages
; will be discarded.

INTGIB:	PUSH P,PKT

INTGI0:	MOVE T1,INTXPW		; Maximum Internet packet size
	CALL GETBLK		; Get a block of free storage
	SKIPN PKT,T1		; Did we get it?
	  JRST INTGIX		; No.

	SETZRO PFLGS,(PKT)	; Clear all internal control flags
	SETONE PFSIZ,(PKT)	; Indicate it is a full size packet
	CALL RETPKT		; Release it to be free input buffer
	CAMGE T1,INTNIB		; Have enough yet?
	  JRST INTGI0		; No.  Get another

INTGIX:	POP P,PKT
	RET

; RETPKT(PKT)		Release packet storage

; If a full size packet is being released and we are low on IMP input
; buffers, the packet will be used as an inut buffer.  Otherwise, it
; gets released to free storage.  Called from INGWAY, TCPIP, TCPRA
; and INTGIB above.

;PKT/	(Extended) Pointer to a packet
;
;	CALL RETPKT
;Ret+1:	Always.  Packet pointer invalid.  T1 has # of input buffers q'd.

	RESCD
RETPKT::JE PFSIZ,(PKT),RETPK1	; Is it a full size packet?
	MOVE T1,INTNFI		; Yes.  Get number currently around
	CAML T1,INTNIB		; Less than required?
	  JRST RETPK1		; No.
	XMOVEI T2,LCLPKT(PKT)	; Get pointer to IMPDV portion
	MOVE T3,MAXWPM		; Size of the IMPDV portion
	STOR T3,NBBSZ,(T2)	; Make look like a good IMPDV pkt buffer
	SETZRO NBQUE,(T2)
	CALL INTLKB		; Lock down ends of the packet
	MOVE T1,T2		; (INTLKB preserves T2)
	PIOFF
	EXCH T2,INTFRI		; Add to list of free input buffers
	STOR T2,NBQUE,(T1)	; Old list is successor of this buf
	AOS T1,INTNFI		; Bump the count to match
	PION
	RET			; Value is number queued

	SWAPCD
RETPK1:	MOVE T1,PKT		; What to return
	CALL RETBLK		; Give it to free storage area
	MOVE T1,INTNFI		; Value is number queued
	RET

; INETUT		Get universal time since midnight

;	CALL INETUT
;Ret+1:	Always, T1 contains 32-bit time since midnight


INETUT::PUSH P,T2
	GTAD			; Get current day,,fraction
	HRRZS T1		; Just fraction
	MUL T1,[↑D<24*60*60*1000>] ; To msec since midnight
	LSH T2,1		; Drop sign
	LSHC T1,↑D<18-1>	; Right justify into T1
	POP P,T2
	RET

; INTINI		Internet Grand Initialization


;	CALL INTINI
;Ret+1:	Always.

; N.B. System startup code clears all resident variables.
; In particular all queues to/from interrupt level are "empty".

INTINI:	MOVEI T1,NINTIB		; Number of input buffers to keep q'd
	MOVEM T1,INTNIB		; for interrupt level.
	NOSKED
	CALL WTBINI		; Initialize Wait Bits
	CALL FREINI		; Initialize Free Storage
	OKSKED

IFN MNET,<
	MOVEI T1,NETSUP		; Point to network up flag
	CALL DISL		; Wait for things to be initialized
>
	CALL GATINI		; Initialize the Gateway

	LOCAL <PIX,PTB,PTL>
	MOVEI PTB,INTPIX+1	; Locate first table
	MOVE PIX,-1(PTB)	; Get # of protocols
	HRRZ PTL,PIX		; Table length
INTINP:	SKIPE T1,.INTPI(PTB)	; xxxINI address
	  CALL (T1)		; Initialize Protocol
	ADD PTB,PTL		; Next Protocol
	AOBJN PIX,INTINP	
	RESTORE
	SETOM INTON		; IP initialized
	RET

	TNXEND
	END